#include <stdio.h>

#include "netlib.h"

KSNetChannel* channel = NULL;
KSNetChannelSink* channel_sink = NULL;

KSNetEventDispatcher* event_dispatcher = NULL;

void on_accept(KSNetListener* listener, KSSockFD peer_fd, struct sockaddr* peer_addr, int peer_len);

void channel_on_connected(KSNetChannel* channel);
int channel_on_parse_size(KSNetChannel* channel, void* buf, size_t len);
void channel_on_packet(KSNetChannel* channel, void* buf, size_t len);
void channel_on_flush(KSNetChannel* channel);

int main(int argc, char* argv[])
{
	KSNetListener* listener = NULL;
	struct sockaddr* listen_addr = NULL;

	printf("yoho~\r\n");

	channel = (KSNetChannel*)calloc(1, sizeof(KSNetChannel));
	channel_sink = (KSNetChannelSink*)calloc(1, sizeof(KSNetChannelSink));
    channel_sink->cb_connected = channel_on_connected;
    channel_sink->cb_parse_size = channel_on_parse_size;
    channel_sink->cb_packet = channel_on_packet;
    channel_sink->cb_flush = channel_on_flush;
	ks_net_channel_init(channel, channel_sink);

	#if defined(_WIN32)
		ks_net_environ_init(1024);
	#endif

	event_dispatcher = (KSNetEventDispatcher*)calloc(1, sizeof(KSNetEventDispatcher));
	assert(event_dispatcher);
	assert(ks_net_event_dispatcher_init(event_dispatcher, 1000));

	listen_addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr));
	assert(ks_net_address_make(listen_addr, "0.0.0.0:5555"));
	listener = (KSNetListener*)calloc(1, sizeof(KSNetListener));
	assert(ks_net_listener_create(listener, listen_addr, 1024, on_accept));
	assert(ks_net_listener_start(listener, event_dispatcher));

	while(1)
	{
		printf("dispatch once\r\n");
		ks_net_event_dispatcher_dispatch(event_dispatcher);
	}

	return (0);
}

void on_accept(KSNetListener* listener, KSSockFD peer_fd, struct sockaddr* peer_addr, int peer_len)
{
	printf("new connection come\r\n");
	assert(ks_net_channel_connect_finish(channel, event_dispatcher, peer_fd));
}

void channel_on_connected(KSNetChannel* channel)
{
    printf("channel: %p connected\r\n", channel);
    channel->slen = 2*1024*1024;
    channel->rlen = 2*1024*1024;
    channel->sbuf = (char*)calloc(1, channel->slen);
    channel->rbuf = (char*)calloc(1, channel->rlen);
    channel->spos = channel->sbuf;
    channel->rpos = channel->rbuf;
}

int channel_on_parse_size(KSNetChannel* channel, void* buf, size_t len)
{
    printf("on parse size - buf: %p, len: %d\r\n", buf, len);
    if(len <= 10)
    {
        return (10);
    } else {
        return (-1);
    }
}

void channel_on_packet(KSNetChannel* channel, void* buf, size_t len)
{
    printf("channel: %p packet: (%p|pos: %p)%s\r\n", channel, buf, channel->rpos, (char*)buf);

    ks_net_channel_write(channel, "hola", 4);
    ks_net_channel_flush(channel);
}

void channel_on_flush(KSNetChannel* channel)
{
    printf("channel on flush\r\n");
}